﻿using LightCAD.Core;
using LightCAD.Drawing;
using LightCAD.Drawing.Actions;
using LightCAD.Runtime;
using SkiaSharp;
using LightCAD.MathLib;
using System.Linq;
using System.Collections.Generic;

namespace QdWater
{
    public class PipeAction : ElementAction
    {
        public PipeAction() { }
     
        public PipeAction(IDocumentEditor docEditor)
         : base(docEditor)
        {
            this.commandCtrl.WriteInfo("命令：Line");
        }
        static PipeAction()
        {
            CreateMethods = new LcCreateMethod[1];
            CreateMethods[0] = new LcCreateMethod()
            {
                Name = "CreatePipe",
                Description = "创建水管",
                Steps = new LcCreateStep[]
                {
                    new LcCreateStep { Name = "Step0", Options = "指定第一个点:" },
                    new LcCreateStep { Name = "Step1", Options = "直墙下一点或 回退(U)]<另一段>:" },
                    new LcCreateStep { Name = "Step2", Options = "指定下一个点或[放弃(U)]:" },
                }
            };
        }
        internal static void Initilize()
        {
            WaterActions.PipeAction = new PipeAction();
            LcDocument.ElementActions.Add(WaterElementType.Pipe, WaterActions.PipeAction);
        }
        private static readonly LcCreateMethod[] CreateMethods;
        private List<Vector2> points;
        private Vector2 firstPoint { get; set; }
        private Line2d? lastLine { get; set; }
        private double pipeWidth = 100;

        private Vector2 secondPoint { get; set; }
        private PointInputer inputer { get; set; }

        public async void ExecCreate(string[] args = null)
        {

            this.points = new List<Vector2>();
            this.StartCreating();
            this.inputer = new PointInputer(this.docEditor);
            var curMethod = CreateMethods[0];

        Step0:
            var step0 = curMethod.Steps[0];
            var result0 = await inputer.Execute(step0.Options);
            //var result0 = await inputer.Execute(step0.Options);

            if (inputer.isCancelled)
            {
                this.Cancel();
                goto End;
            }

            // zcb: 增加Res0为空的判定
            if (result0 == null)
            {
                this.Cancel();
                goto End;
            }

            if (result0.ValueX == null)
            {
                if (result0.Option != null)
                {
                    goto Step0;
                    //TODO:AutoCAD画线输入一个数字，是怎么确定点的？
                }
                else
                {
                    goto Step0;
                }
            }

            this.firstPoint = (Vector2)result0.ValueX;

        Step1:
            var step1 = curMethod.Steps[1];
            if (this.points.Count >= 2)
            {
                step1 = curMethod.Steps[2];
            }

            var result1 = await inputer.Execute(step1.Options);
            if (inputer.isCancelled)
            {
                this.Cancel();
                goto End;
            }



            if (result1.Option != null)
            {
                if (result1.Option == "W")
                {

                }
                else if (result1.Option == " ")
                {
                    goto End;
                }
                else if (result1.ValueX != null)
                {
                    Vector2 pointB = (Vector2)result1.ValueX;
                    Vector2 direction = (pointB - firstPoint).Normalize();
                    result1.ValueX = firstPoint + direction * double.Parse(result1.Option);
                    //TODO:AutoCAD画线输入一个数字，是怎么确定点的？
                }
                else
                {
                    goto Step1;
                }
            }

            this.secondPoint = (Vector2)result1.ValueX;


            CreatePipe(firstPoint, secondPoint);
            firstPoint = secondPoint;
            goto Step1;

        End:
            this.inputer = null;
            this.EndCreating();
        }
        private bool CreatePipe(Vector2 sp, Vector2 ep, double width = 200)
        {
            Line2d line2D = new Line2d();
            line2D.Start = sp;
            line2D.End = ep;
            var doc = this.docRt.Document;
            var pipe = doc.CreateObject<LcPipe>();
            pipe.BaseCurve = line2D;
            // pipe.Curves.Add(line2D);
            pipe.Width = pipeWidth;
            pipe.Height = 3000;
            pipe.Bottom = 0;
            pipe.CreateShapeCurves();
            DisposePipes(pipe);

            this.docRt.Action.ClearSelects();
            return true;
        }
        private List<LcPipe> GetCrossPipes(Line2d line2d)
        {
            var lcElements = this.docRt.Document.ModelSpace.Elements.Where((ele) => ele.Type == WaterElementType.Pipe).ToList();
            List<LcPipe> lcPipes = new List<LcPipe>();
            foreach (LcPipe pipe in lcElements)
            {
                if (line2d != pipe.BaseLine)
                {
                    if (pipe.BaseLine.Start.Similarity(line2d.Start) || pipe.BaseLine.Start.Similarity(line2d.End) || pipe.BaseLine.End.Similarity(line2d.Start) || pipe.BaseLine.End.Similarity(line2d.End))
                    {
                        lcPipes.Add(pipe);
                    }
                    else
                        if (Line2d.CrossLine(line2d, pipe.BaseLine, pipe.Width / 2))
                    {
                        lcPipes.Add(pipe);
                    }
                }
            }
            return lcPipes;
        }
        private void DisposePipes(LcPipe pipe, bool Create = true)
        {
            List<LcPipe> Crosspipes = GetCrossPipes(pipe.BaseLine);
            if (Crosspipes.Count > 0)
            {
                foreach (LcPipe item in Crosspipes)
                {
                    if (item.BaseLine.Start.Similarity(pipe.BaseLine.Start) || item.BaseLine.Start.Similarity(pipe.BaseLine.End) || item.BaseLine.End.Similarity(pipe.BaseLine.Start) || item.BaseLine.End.Similarity(pipe.BaseLine.End))
                    {
                        CornerPipes(pipe, item);
                        AssociateElement associateElement = new AssociateElement();
                        associateElement.Element = item;
                        associateElement.Name = "Pipe";
                        associateElement.Tag = pipe.Id;
                        associateElement.Type = AssociateType.Connect;
                        if (pipe.AssociateElements.Where(x => x.Element == item).Count() == 0)
                        {
                            pipe.AssociateElements.Add(associateElement);
                        }
                    }
                    else
                    if (Vector2.Distance(item.BaseLine.Start, pipe.BaseLine.Start) < pipe.Width / 2 || Vector2.Distance(item.BaseLine.Start, pipe.BaseLine.End) < pipe.Width / 2 || Vector2.Distance(item.BaseLine.End, pipe.BaseLine.Start) < pipe.Width / 2 || Vector2.Distance(item.BaseLine.End, pipe.BaseLine.End) < pipe.Width / 2)
                    {
                        if (Vector2.Distance(item.BaseLine.Start, pipe.BaseLine.Start) < pipe.Width / 2)
                        {
                            pipe.BaseLine.Start = item.BaseLine.Start;
                        }
                        if (Vector2.Distance(item.BaseLine.End, pipe.BaseLine.Start) < pipe.Width / 2)
                        {
                            pipe.BaseLine.Start = item.BaseLine.End;
                        }
                        if (Vector2.Distance(item.BaseLine.Start, pipe.BaseLine.End) < pipe.Width / 2)
                        {
                            pipe.BaseLine.End = item.BaseLine.Start;

                        }
                        if (Vector2.Distance(item.BaseLine.End, pipe.BaseLine.End) < pipe.Width / 2)
                        {
                            pipe.BaseLine.End = item.BaseLine.End;
                        }
                        pipe.CreateShapeCurves();
                        CornerPipes(pipe, item);
                        AssociateElement associateElement = new AssociateElement();
                        associateElement.Element = item;
                        associateElement.Name = "Pipe";
                        associateElement.Tag = pipe.Id;
                        associateElement.Type = AssociateType.Connect;
                        if (pipe.AssociateElements.Where(x => x.Element == item).Count() == 0)
                        {
                            pipe.AssociateElements.Add(associateElement);
                        }
                    }
                    else
                    {
                        Vector2 cp = Line2d.GetCrossVector(pipe.BaseLine, item.BaseLine);
                        double sc = Vector2.Distance(cp, pipe.BaseLine.Start);
                        double ec = Vector2.Distance(cp, pipe.BaseLine.End);
                        double cl = sc < ec ? sc : ec;
                        double sc1 = Vector2.Distance(cp, item.BaseLine.Start);
                        double ec1 = Vector2.Distance(cp, item.BaseLine.End);
                        double cl1 = sc1 < ec1 ? sc1 : ec1;
                        if (cl < (item.Width / 2))//交点小于墙宽就算 转角墙
                        {
                            if (sc < ec)
                            {
                                ConnectPipe(pipe, item, pipe.BaseLine.Start);
                            }
                            else
                            {
                                ConnectPipe(pipe, item, pipe.BaseLine.End);

                            }
                        }
                        else if (cl1 < (pipe.Width / 2))//交点小于墙宽就算 转角墙
                        {
                            if (sc1 < ec1)
                            {
                                ConnectPipe(item, pipe, item.BaseLine.Start);
                            }
                            else
                            {
                                ConnectPipe(item, pipe, item.BaseLine.End);

                            }
                        }
                        else//交叉墙 需要打断
                        {
                            CrossPipe(pipe, item);
                            AssociateElement associateElement = new AssociateElement();
                            associateElement.Element = item;

                            associateElement.Name = "Pipe";
                            associateElement.Tag = pipe.Id;
                            associateElement.Type = AssociateType.Cross;
                            if (pipe.AssociateElements.Where(x => x.Element == item).Count() == 0)
                            {
                                pipe.AssociateElements.Add(associateElement);
                            }
                        }
                    }
                }
                if (Create)
                    this.docRt.Document.ModelSpace.InsertElement(pipe);
            }
            else
            {
                if (Create)
                    this.docRt.Document.ModelSpace.InsertElement(pipe);
            }
        }
        private void CornerPipes(LcPipe npipe, LcPipe opipe)
        {
            //管子相交自动剪裁为管件提供位置
            LcPipeFitting lcPipeFitting = this.docRt.Document.CreateObject<LcPipeFitting>();
            var intersect = LcGeoUtils.IntersectLineLine(npipe.BaseLine.Start, npipe.BaseLine.End, opipe.BaseLine.Start, opipe.BaseLine.End);
            var CentralPoint = intersect.points.FirstOrDefault();
            Vector2 direction = (CentralPoint - npipe.BoundingBox.Center).Normalize();
            Vector2 direction2 = (CentralPoint - opipe.BoundingBox.Center).Normalize();
            var newPoint =CentralPoint - direction * this.pipeWidth;
            var newPoint2 =CentralPoint - direction2 * this.pipeWidth;
            if ((npipe.BaseLine.Start-CentralPoint).Length() > (npipe.BaseLine.End - CentralPoint).Length())
            {
                npipe.BaseLine.End = newPoint;
            }
            else
            {
                npipe.BaseLine.Start = newPoint;
            }
            if ((opipe.BaseLine.Start - CentralPoint).Length() > (opipe.BaseLine.End - CentralPoint).Length())
            {
                opipe.BaseLine.End = newPoint2;
            }
            else
            {
                opipe.BaseLine.Start = newPoint2;
            }
            lcPipeFitting.CentralPoint = CentralPoint;
            lcPipeFitting.linkPipes.Add(npipe);
            lcPipeFitting.linkPipes.Add(opipe);
            npipe.CreateShapeCurves();
            opipe.CreateShapeCurves();
            this.docRt.Document.ModelSpace.InsertElement(lcPipeFitting);


            //List<Line2d> reline2d = new List<Line2d>();

            //Line2d nline1 = new Line2d { Start = npipe.Points[0], End = npipe.Points[1] };
            //Line2d nline2 = new Line2d { Start = npipe.Points[2], End = npipe.Points[3] };
            //Line2d oline1 = new Line2d { Start = opipe.Points[0], End = opipe.Points[1] };
            //Line2d oline2 = new Line2d { Start = opipe.Points[2], End = opipe.Points[3] };
            //if (npipe.BaseLine.Start.Similarity(opipe.BaseLine.Start))
            //{
            //    removelinebyPoint(npipe.Curves, opipe.Curves, npipe.BaseLine.Start, opipe.BaseLine.Start);


            //    if (Line2d.CrossLine(nline1, oline1))
            //    {
            //        if (!Line2d.CrossLine(nline1, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline1, oline1);
            //            Vector2d yp = Line2d.GetCrossVector(nline2, oline2);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 1, 1);

            //        }
            //        else
            //        {
            //            Vector2d p2 = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d p1 = Line2d.GetCrossVector(nline1, oline1);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.Start) > Vector2d.Distance(p2, npipe.BaseLine.Start))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline1);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline2);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 1, 1);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 1, 2);
            //            }

            //        }
            //    }
            //    else if (Line2d.CrossLine(nline1, oline2))
            //    {

            //        if (!Line2d.CrossLine(nline2, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 1, 2);
            //        }
            //        else
            //        {
            //            Vector2d p1 = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d p2 = Line2d.GetCrossVector(nline2, oline2);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.Start) > Vector2d.Distance(p2, npipe.BaseLine.Start))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 1, 2);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 2, 2);
            //            }
            //        }

            //    }
            //    else if (Line2d.CrossLine(nline2, oline1))
            //    {
            //        if (!Line2d.CrossLine(nline2, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline2, oline1);
            //            Vector2d yp = Line2d.GetCrossVector(nline1, oline2);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 2, 1);
            //        }
            //        else
            //        {
            //            Vector2d p1 = Line2d.GetCrossVector(nline2, oline1);
            //            Vector2d p2 = Line2d.GetCrossVector(nline2, oline2);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.Start) > Vector2d.Distance(p2, npipe.BaseLine.Start))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline1);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline2);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 2, 1);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 2, 2);
            //            }
            //        }
            //    }
            //    else if (Line2d.CrossLine(nline2, oline2))
            //    {
            //        Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //        Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //        changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.Start, 2, 2);
            //    }
            //}
            //else if (npipe.BaseLine.Start.Similarity(opipe.BaseLine.End))
            //{
            //    removelinebyPoint(npipe.Curves, opipe.Curves, npipe.BaseLine.Start, opipe.BaseLine.End);


            //    if (Line2d.CrossLine(nline1, oline1))
            //    {

            //        if (!Line2d.CrossLine(nline1, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline1, oline1);
            //            Vector2d yp = Line2d.GetCrossVector(nline2, oline2);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 1, 1);

            //        }
            //        else
            //        {
            //            Vector2d p2 = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d p1 = Line2d.GetCrossVector(nline1, oline1);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.Start) > Vector2d.Distance(p2, npipe.BaseLine.Start))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline1);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline2);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 1, 1);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 1, 2);
            //            }

            //        }

            //    }
            //    else if (Line2d.CrossLine(nline1, oline2))
            //    {
            //        if (!Line2d.CrossLine(nline2, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 1, 2);
            //        }
            //        else
            //        {
            //            Vector2d p1 = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d p2 = Line2d.GetCrossVector(nline2, oline2);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.Start) > Vector2d.Distance(p2, npipe.BaseLine.Start))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 1, 2);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 2, 2);
            //            }
            //        }

            //    }
            //    else if (Line2d.CrossLine(nline2, oline1))
            //    {
            //        if (!Line2d.CrossLine(nline2, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline2, oline1);
            //            Vector2d yp = Line2d.GetCrossVector(nline1, oline2);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 2, 1);
            //        }
            //        else
            //        {
            //            Vector2d p1 = Line2d.GetCrossVector(nline2, oline1);
            //            Vector2d p2 = Line2d.GetCrossVector(nline2, oline2);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.Start) > Vector2d.Distance(p2, npipe.BaseLine.Start))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline1);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline2);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 2, 1);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 2, 2);
            //            }
            //        }
            //    }
            //    else if (Line2d.CrossLine(nline2, oline2))
            //    {
            //        Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //        Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //        changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.Start, opipe.BaseLine.End, 2, 2);
            //    }
            //}
            //else if (npipe.BaseLine.End.Similarity(opipe.BaseLine.Start))
            //{
            //    removelinebyPoint(npipe.Curves, opipe.Curves, npipe.BaseLine.End, opipe.BaseLine.Start);


            //    if (Line2d.CrossLine(nline1, oline1))
            //    {

            //        if (!Line2d.CrossLine(nline1, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline1, oline1);
            //            Vector2d yp = Line2d.GetCrossVector(nline2, oline2);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 1, 1);

            //        }
            //        else
            //        {
            //            Vector2d p2 = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d p1 = Line2d.GetCrossVector(nline1, oline1);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.End) > Vector2d.Distance(p2, npipe.BaseLine.End))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline1);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline2);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 1, 1);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 1, 2);
            //            }

            //        }

            //    }
            //    else if (Line2d.CrossLine(nline1, oline2))
            //    {


            //        if (!Line2d.CrossLine(nline2, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 1, 2);
            //        }
            //        else
            //        {
            //            Vector2d p1 = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d p2 = Line2d.GetCrossVector(nline2, oline2);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.End) > Vector2d.Distance(p2, npipe.BaseLine.End))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 1, 2);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 2, 2);
            //            }
            //        }

            //    }
            //    else if (Line2d.CrossLine(nline2, oline1))
            //    {

            //        if (!Line2d.CrossLine(nline2, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline2, oline1);
            //            Vector2d yp = Line2d.GetCrossVector(nline1, oline2);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 2, 1);
            //        }
            //        else
            //        {
            //            Vector2d p1 = Line2d.GetCrossVector(nline2, oline1);
            //            Vector2d p2 = Line2d.GetCrossVector(nline2, oline2);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.End) > Vector2d.Distance(p2, npipe.BaseLine.End))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline1);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline2);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 2, 1);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 2, 2);
            //            }
            //        }
            //    }
            //    else if (Line2d.CrossLine(nline2, oline2))
            //    {
            //        Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //        Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //        changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.Start, 2, 2);
            //    }
            //}
            //else
            //{
            //    removelinebyPoint(npipe.Curves, opipe.Curves, npipe.BaseLine.End, opipe.BaseLine.End);


            //    if (Line2d.CrossLine(nline1, oline1))
            //    {

            //        if (!Line2d.CrossLine(nline1, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline1, oline1);
            //            Vector2d yp = Line2d.GetCrossVector(nline2, oline2);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 1, 1);

            //        }
            //        else
            //        {
            //            Vector2d p2 = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d p1 = Line2d.GetCrossVector(nline1, oline1);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.End) > Vector2d.Distance(p2, npipe.BaseLine.End))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline1);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline2);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 1, 1);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 1, 2);
            //            }

            //        }


            //    }
            //    else if (Line2d.CrossLine(nline1, oline2))
            //    {

            //        if (!Line2d.CrossLine(nline2, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 1, 2);
            //        }
            //        else
            //        {
            //            Vector2d p1 = Line2d.GetCrossVector(nline1, oline2);
            //            Vector2d p2 = Line2d.GetCrossVector(nline2, oline2);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.End) > Vector2d.Distance(p2, npipe.BaseLine.End))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline1, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline2, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 1, 2);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 2, 2);
            //            }
            //        }

            //    }
            //    else if (Line2d.CrossLine(nline2, oline1))
            //    {


            //        if (!Line2d.CrossLine(nline2, oline2))
            //        {
            //            Vector2d jp = Line2d.GetCrossVector(nline2, oline1);
            //            Vector2d yp = Line2d.GetCrossVector(nline1, oline2);
            //            changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 2, 1);
            //        }
            //        else
            //        {
            //            Vector2d p1 = Line2d.GetCrossVector(nline2, oline1);
            //            Vector2d p2 = Line2d.GetCrossVector(nline2, oline2);
            //            if (Vector2d.Distance(p1, npipe.BaseLine.End) > Vector2d.Distance(p2, npipe.BaseLine.End))
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline1);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline2);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 2, 1);
            //            }
            //            else
            //            {
            //                Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //                Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //                changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 2, 2);
            //            }
            //        }
            //    }
            //    else if (Line2d.CrossLine(nline2, oline2))
            //    {
            //        Vector2d jp = Line2d.GetCrossVector(nline2, oline2);
            //        Vector2d yp = Line2d.GetCrossVector(nline1, oline1);
            //        changepoint(npipe.Curves, opipe.Curves, jp, yp, npipe.Points, opipe.Points, npipe.BaseLine.End, opipe.BaseLine.End, 2, 2);
            //    }
            //}
        }
        private void ConnectPipe(LcPipe npipe, LcPipe opipe, Vector2 p)
        {
            Line2d nline1 = new Line2d { Start = npipe.Points[0], End = npipe.Points[1] };
            Line2d nline2 = new Line2d { Start = npipe.Points[2], End = npipe.Points[3] };
            Line2d oline1 = new Line2d { Start = opipe.Points[0], End = opipe.Points[1] };
            Line2d oline2 = new Line2d { Start = opipe.Points[2], End = opipe.Points[3] };
            List<Line2d> removes = new List<Line2d>();
            foreach (Line2d item in npipe.Curves)
            {
                if (Line2d.PointInLine(item, p))
                {
                    removes.Add(item);
                }

            }
            foreach (Line2d item in removes)
                npipe.Curves.Remove(item);



            Dictionary<Line2d, List<Line2d>> dls = new Dictionary<Line2d, List<Line2d>>();
            foreach (Line2d item in opipe.Curves)
            {
                if (Line2d.CrossLine(item, nline1) && Line2d.CrossLine(item, nline2))
                {
                    dls.Add(item, Line2d.BreakLineBy2line(item, nline1, nline2));

                }
            }
            foreach (var item in dls)
            {
                opipe.Curves.Remove(item.Key); opipe.Curves.AddRange(item.Value);
            }


            foreach (Line2d item in npipe.Curves)
            {
                if (Line2d.CrossLine(item, oline1))
                {
                    Vector2 cp = Line2d.GetCrossVector(item, oline1);
                    double sc = Vector2.Distance(cp, item.Start);
                    double ec = Vector2.Distance(cp, item.End);
                    if (sc < ec)
                    {
                        item.Start = cp;
                    }
                    else
                    {
                        item.End = cp;
                    }

                }
                if (Line2d.CrossLine(item, oline2))
                {
                    Vector2 cp = Line2d.GetCrossVector(item, oline2);
                    double sc = Vector2.Distance(cp, item.Start);
                    double ec = Vector2.Distance(cp, item.End);
                    if (sc < ec)
                    {
                        item.Start = cp;
                    }
                    else
                    {
                        item.End = cp;
                    }
                }
            }

            if (Line2d.CrossLine(nline1, oline1))
            {
                Vector2 cp = Line2d.GetCrossVector(nline1, oline1);
                double sc = Vector2.Distance(cp, nline1.Start);
                double ec = Vector2.Distance(cp, nline1.End);
                if (sc < ec)
                {
                    npipe.Points[0] = cp;
                }
                else
                {
                    npipe.Points[1] = cp;
                }
            }
            else if (Line2d.CrossLine(nline1, oline2))
            {
                Vector2 cp = Line2d.GetCrossVector(nline1, oline2);
                double sc = Vector2.Distance(cp, nline1.Start);
                double ec = Vector2.Distance(cp, nline1.End);
                if (sc < ec)
                {
                    npipe.Points[0] = cp;
                }
                else
                {
                    npipe.Points[1] = cp;
                }
            }
            if (Line2d.CrossLine(nline2, oline1))
            {
                Vector2 cp = Line2d.GetCrossVector(nline2, oline1);
                double sc = Vector2.Distance(cp, nline2.Start);
                double ec = Vector2.Distance(cp, nline2.End);
                if (sc < ec)
                {
                    npipe.Points[2] = cp;
                }
                else
                {
                    npipe.Points[3] = cp;
                }
            }
            else if (Line2d.CrossLine(nline2, oline2))
            {
                Vector2 cp = Line2d.GetCrossVector(nline2, oline2);
                double sc = Vector2.Distance(cp, nline2.Start);
                double ec = Vector2.Distance(cp, nline2.End);
                if (sc < ec)
                {
                    npipe.Points[2] = cp;
                }
                else
                {
                    npipe.Points[3] = cp;
                }
            }
            if (Line2d.CrossLine(npipe.BaseLine, oline1))
            {
                Vector2 cp = Line2d.GetCrossVector(npipe.BaseLine, oline1);
                double sc = Vector2.Distance(cp, npipe.BaseLine.Start);
                double ec = Vector2.Distance(cp, npipe.BaseLine.End);
                if (sc < ec)
                {
                    Line2d basel = new Line2d();
                    basel.Start = cp;
                    basel.End = npipe.BaseLine.End;
                    npipe.BaseCurve = basel;

                }
                else
                {
                    Line2d basel = new Line2d();
                    basel.Start = npipe.BaseLine.Start;
                    basel.End = cp;
                    npipe.BaseCurve = basel;

                }
            }
            else if (Line2d.CrossLine(npipe.BaseLine, oline2))
            {
                Vector2 cp = Line2d.GetCrossVector(npipe.BaseLine, oline2);
                double sc = Vector2.Distance(cp, npipe.BaseLine.Start);
                double ec = Vector2.Distance(cp, npipe.BaseLine.End);
                if (sc < ec)
                {
                    Line2d basel = new Line2d();
                    basel.Start = cp;
                    basel.End = npipe.BaseLine.End;
                    npipe.BaseCurve = basel;

                }
                else
                {
                    Line2d basel = new Line2d();
                    basel.Start = npipe.BaseLine.Start;
                    basel.End = cp;
                    npipe.BaseCurve = basel;

                }
            }
        }
        /// <summary>
        /// //交叉管打断
        /// </summary>
        /// <param name="npipe"></param>
        /// <param name="opipe"></param>
        private void CrossPipe(LcPipe npipe, LcPipe opipe)
        {

            Line2d nline1 = new Line2d { Start = npipe.Points[0], End = npipe.Points[1] };
            Line2d nline2 = new Line2d { Start = npipe.Points[2], End = npipe.Points[3] };
            Line2d oline1 = new Line2d { Start = opipe.Points[0], End = opipe.Points[1] };
            Line2d oline2 = new Line2d { Start = opipe.Points[2], End = opipe.Points[3] };
            Dictionary<Line2d, List<Line2d>> dls = new Dictionary<Line2d, List<Line2d>>();
            foreach (Line2d item in npipe.Curves)
            {
                if (Line2d.CrossLine(item, oline1) && Line2d.CrossLine(item, oline2))
                {
                    dls.Add(item, Line2d.BreakLineBy2line(item, oline1, oline2));

                }
            }
            foreach (var item in dls)
            {
                npipe.Curves.Remove(item.Key);
                npipe.Curves.AddRange(item.Value);
            }
            dls = new Dictionary<Line2d, List<Line2d>>();
            foreach (Line2d item in opipe.Curves)
            {
                if (Line2d.CrossLine(item, nline1) && Line2d.CrossLine(item, nline2))
                {
                    dls.Add(item, Line2d.BreakLineBy2line(item, nline1, nline2));

                }
            }
            foreach (var item in dls)
            {
                opipe.Curves.Remove(item.Key); opipe.Curves.AddRange(item.Value);
            }
        }
        private void removelinebyPoint(List<Curve2d> nc, List<Curve2d> oc, Vector2 np, Vector2 op)
        {
            List<Line2d> reline2d = new List<Line2d>();
            reline2d = new List<Line2d>();
            foreach (Line2d item in nc)
            {
                if (Line2d.PointInLine(item, np))
                {
                    reline2d.Add(item);
                    break;
                }
            }
            foreach (var item in reline2d)
                nc.Remove(item);
            reline2d = new List<Line2d>();
            foreach (Line2d item in oc)
            {
                if (Line2d.PointInLine(item, op))
                {
                    reline2d.Add(item);
                    break;
                }
            }
            foreach (var item in reline2d)
                oc.Remove(item);
        }


        public override void Draw(SKCanvas canvas, LcElement element, Vector2 offset)
        {
            Matrix3 matrix = Matrix3.GetTranslate(offset);
            var lcPipe = element as LcPipe;
            var mstart = matrix.MultiplyPoint(lcPipe.BaseLine.Start);
            var mend = matrix.MultiplyPoint(lcPipe.BaseLine.End);
            var start = this.vportRt.ConvertWcsToScr(mstart).ToSKPoint();
            var end = this.vportRt.ConvertWcsToScr(mend).ToSKPoint();

            //using (var elePen =  new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
            //{
            //    canvas.DrawLine(start, end, elePen);
            //}
            foreach (var item in lcPipe.Curves)
            {
                Line2d line2D = item as Line2d;
                mstart = matrix.MultiplyPoint(line2D.Start);
                mend = matrix.MultiplyPoint(line2D.End);
                start = this.vportRt.ConvertWcsToScr(mstart).ToSKPoint();
                end = this.vportRt.ConvertWcsToScr(mend).ToSKPoint();
                var pen = this.GetDrawPen(element);
                if (pen == LightCAD.Runtime.Constants.defaultPen)
                {
                    using (var elePen = new SKPaint { Color = new SKColor(element.GetColorValue()), IsStroke = true })
                    {
                        canvas.DrawLine(start, end, elePen);
                    }
                }
                else
                {
                    canvas.DrawLine(start, end, pen);
                }
            }
        }

        public override ControlGrip[] GetControlGrips(LcElement element)
        {
            var group = element as LcPipe;
            var grips = new List<ControlGrip>();
            var gripCenter = new ControlGrip
            {
                Element = group,
                Name = "Center",
                Position = group.BoundingBox.Center,

            };
            grips.Add(gripCenter);

            var gripStart = new ControlGrip
            {
                Element = group,
                Name = "Start",
                Position = group.BaseLine.Start
            };
            grips.Add(gripStart);
            var gripEnd = new ControlGrip
            {
                Element = group,
                Name = "End",
                Position = group.BaseLine.End
            };
            grips.Add(gripEnd);



            return grips.ToArray();
        }
    }
}